package icu.shaoyayu.common.log.aop;

import com.google.gson.Gson;
import icu.shaoyayu.common.log.CustomLogLogger;
import icu.shaoyayu.common.log.WebLoggingEvent;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @author shaoyayu
 * @date 2022/2/10
 * @apiNote
 */
@Aspect
public class WebLoggerAspect {
    @Pointcut("@annotation(icu.shaoyayu.common.log.aop.WebLogger)")
    public void log() {}

    @Autowired
    private CustomLogLogger customLogLogger;

    @Around("log()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();
        // 记录请求的方式 <user:ip:path:方法:<参数>>
        System.out.println("==========================================Request==========================================");
        System.out.println("发起请求：{IP:["+ request.getRemoteAddr() +"],URL:[ " +request.getRequestURL().toString()+"]}");
        System.out.println("Method：" + request.getMethod().toString());
        System.out.println("Description：" + getLogValue(joinPoint));
        //打印controller全路径及method
        System.out.println("Class Method：" + joinPoint.getSignature().getDeclaringTypeName() + "," + joinPoint.getSignature().getName());
        System.out.println("请求参数：" + new Gson().toJson(joinPoint.getArgs()));
        long startTime = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        // TODO 只需要机制返回的状态即可，不需要记录返回的 data 的内容，
        System.out.println("Response："+ new Gson().toJson(result));
        System.out.println("耗时："+(System.currentTimeMillis()-startTime));
        System.out.println("==========================================End==========================================");
        WebLoggingEvent webLoggingEvent = new WebLoggingEvent();
        webLoggingEvent.setUri(request.getRequestURL().toString());
        customLogLogger.output(webLoggingEvent);
        return result;
    }

    private String getLogValue(JoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        WebLogger  webLogger = method.getAnnotation(WebLogger.class);
        return webLogger.value();
    }
}
